<template>
    <div class="main">
        <reconnect v-if="reConnectLoading" :text="infoText"></reconnect>
        <div style="width: 80px;height: 100%;">
            <userinfo @exit="handleExit"></userinfo>
        </div>
        <n-split v-if="!isMobile" direction="horizontal" default-size="264px" style="height: 100vh" max="300px"
            min="244px">
            <template #1>
                <div style="width: 100%;height: 100vh;display: flex;">
                    <div style="flex:1;height: 100%;">
                        <friendlist :list="friendlistData" @chooseMember="handleChooseMember"></friendlist>
                    </div>
                </div>
            </template>
            <template #2>

                <MessageContent :friendlistData="friendlistData" :msglist="msglist" :loadingLock="loadingLock" ref="msgcontentCom" :reciver="reciver"
                    @ScrollToTop="handleScrollToTop" @sendMsg="handleSendMsg" :key="reciver">
                </MessageContent>
            </template>
        </n-split>
        <template v-else>
            <div style="width: 100%;height: 100vh;display: flex;">
                <div v-if="!isDetail" style="flex:1;height: 100%;">
                    <friendlist :list="friendlistData" @chooseMember="handleChooseMember"></friendlist>
                </div>
                <MessageContent :friendlistData="friendlistData" :msglist="msglist" :loadingLock="loadingLock" ref="msgcontentCom" :reciver="reciver"
                    @sendMsg="handleSendMsg" :isMobile="isMobile" @ScrollToTop="handleScrollToTop" :key="reciver" v-else
                    @back="isDetail = false">
                </MessageContent>
            </div>
        </template>


    </div>
</template>

<script setup lang="ts">
import friendlist from '@/components/friendlist.vue';
import MessageContent from '@/components/messageContent.vue';
import reconnect from '@/components/reconnect.vue';
import userinfo from '@/components/userinfo.vue';
import { useWindowSize } from '@vueuse/core'
import storage from '@/utils/storage'
import { ref, getCurrentInstance, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
// import { sendToServer } from '@/utils/socket';
import { getChatHistory } from '@/api/chat';
import { createDiscreteApi } from 'naive-ui'
import { statusToNumber } from "@/utils/constData"
const { message, notification } = createDiscreteApi(
    ['message', 'dialog', 'notification', 'loadingBar', 'modal']
)
const sendToServer = (socket: any, message: any) => {
    if (socket.readyState === WebSocket.OPEN) {
        socket.send(JSON.stringify(message));
        if (message.type !== 'pong') {
            console.log(`已发送消息到服务器${message.type}`);
        }

    } else {
        console.log('WebSocket 连接未打开，无法发送消息');
        startReconnect()
    }
}
const router = useRouter()
const { proxy } = getCurrentInstance() as any

const reciver = ref<any>(null)
const friendlistData = ref<any>([])
const wsBaseUrl = ref(`${import.meta.env.VITE_WSURL}`);
const isMobile = ref<boolean>(false)
const isDetail = ref<boolean>(false)
const msglist = ref<any>([])
// 监听窗口大小变化
window.addEventListener('resize', () => {
    initCheckIsMobile()
})
const infoText = ref("断线重连中...")
const handleExit = () => {
    sendToServer(socket.value, { type: 'disconnect', data: { uid: storage.get('userinfo')._id } })

    storage.clear()
    router.replace('/login')
    message.success('退出登录成功')
    socket.value.close()
    clearInterval(reconnectInterval.value)
    reconnectInterval.value = null
    reConnectLoading.value = false
    rcount.value = 0
    socket.value = null
}
const initCheckIsMobile = () => {
    const { width } = useWindowSize()
    if (width.value < 600) {
        isMobile.value = true
    } else {
        isMobile.value = false
    }
}
initCheckIsMobile()
const handleChooseMember = (user: any) => {
    if (isMobile.value) {
        isDetail.value = true;
    }
    reciver.value = user
    if (reciver.value) {
        getChatHistory({
            tid: reciver.value._id,
            fid: storage.get("userinfo")._id,
        }).then((res) => {
            msglist.value = res.data.reverse()
            // 滚动到底部

        });
    } else {
        message.error('请先选择一个好友')
    }

}
const rcount = ref(0)
const reconnectInterval = ref<any>(null)
const socket = ref<any>(null)
const loadingLock = ref(false)
const handleScrollToTop = (time: number) => {
    if (reciver.value) {
        if (!loadingLock.value) {
            loadingLock.value = true
            getChatHistory({
                tid: reciver.value._id,
                fid: storage.get("userinfo")._id,
                endTimestamp: time
            }).then((res) => {
                if (res.data.length == 0) {
                    message.info('没有更多消息了')
                    return
                }
                msglist.value = [...msglist.value, ...res.data.reverse()]
                proxy.$refs.msgcontentCom.solidedown()

            }).finally(() => {
                loadingLock.value = false

            });
        }
    } else {
        message.error('请先选择一个好友')
    }

}

const socketConnect = () => {

    if (rcount.value > 0) {
        console.log(`当前第${rcount.value}次重新连接`)
    }
    rcount.value++
    let token = storage.get('token')
    // 创建一个新的 Websocket 实例
    socket.value = new WebSocket(`${wsBaseUrl.value}/mws?token=${token}`);
    socket.value.onerror = (_event: any) => {
        // 判断当前连接状态
        if (socket.value.readyState === WebSocket.CLOSED) {
            console.warn("WebSocket 已经关闭，无法恢复");
            infoText.value = "WebSocket 已经关闭，无法恢复"
        } else if (socket.value.readyState === WebSocket.CLOSING) {
            console.warn("WebSocket 正在关闭...");
            infoText.value = "WebSocket 正在关闭..."
        }
        // startReconnect()
    };
    //1验证身份
    //2链接socket
    let userinfo = storage.get('userinfo')
    // 连接打开时触发

    socket.value.onopen = () => {
        if (rcount.value > 1) {
            console.log(`WebSocket第${rcount.value}重连成功`);
        } else {
            console.log('WebSocket连接已建立');
        }

        sendToServer(socket.value, { type: 'connect', data: { uid: userinfo._id } })
        // 接收消息时触发
        if (reconnectInterval.value) {
            clearInterval(reconnectInterval.value);
            reconnectInterval.value = null
            reConnectLoading.value = false
        }

    };

    socket.value.close = (_info: any) => {
        console.log('WebSocket 连接已关闭');
        startReconnect()
    };

    socket.value.onmessage = (event: any) => {
        const message = JSON.parse(event.data);
        switch (message.type) {
            case 'list':
                // 处理接收到的消息
                friendlistData.value = message.data.filter((item: any) => item._id != storage.get('userinfo')._id)
                break;
            case 'message':
                msglist.value = message.data
                // 滚动到底部

                break;
            case 'ping':

                // 滚动到底部
                sendToServer(socket.value, { type: 'pong', data: 'pong' })

                break;
            case 'connect':
                // 处理连接成功的消息
                if (message.data.code == 401) {
                    //    message.error('身份验证失败，请重新登录')
                    notification.error({
                        title: '身份验证失败',
                        content: '请重新登录',
                        duration: 0,
                        closable: true,
                        onClose: () => {
                            storage.clear()
                            router.replace('/login')
                        }
                    })
                    socket.value.close()
                    clearInterval(reconnectInterval.value)
                    reconnectInterval.value = null
                    reConnectLoading.value = false
                    rcount.value = 0
                    socket.value = null
                    storage.clear()
                    router.replace('/')
                    return;
                }
                console.log('连接成功:', message.data);
                break;
            default:
                console.log('接收到未知消息类型:x', message.type);
        }
        if (message.type !== 'ping') {
            console.log('接收到消息:', message.type);
        }

    }

}

const MAXCOUNT = 6 //最大重连次数
const INTERVAL = 2 * 1000 //重连间隔
const reConnectLoading = ref<boolean>(false)

const startReconnect = () => {
    reConnectLoading.value = true //重连loading
    if (!reconnectInterval.value) {
        reconnectInterval.value = setInterval(() => {
            if (statusToNumber[socket.value.readyState] == 'CLOSED') {
                if (rcount.value <= MAXCOUNT) {
                    socketConnect()
                } else {
                    clearInterval(reconnectInterval.value)
                    reconnectInterval.value = null
                    reConnectLoading.value = false
                    message.error('网络连接失败，请检查网络')
                    router.replace('/login')
                }

            } else {

                if (statusToNumber[socket.value.readyState] == 'OPEN') {
                    if (rcount.value <= MAXCOUNT) {
                        socketConnect()
                    } else {
                        clearInterval(reconnectInterval.value)
                        reconnectInterval.value = null
                        reConnectLoading.value = false
                        message.error('网络连接失败，请检查网络')
                        router.replace('/login')
                    }
                } else {
                    console.log('OPEN 下 重连wtf')
                }
                // clearInterval(reconnectInterval.value)
                // reconnectInterval.value = null
                // reConnectLoading.value = false
            }
        }, INTERVAL)
    } else {
        console.log('重连中..')
    }
}
socketConnect()

onBeforeUnmount(() => {
    if (socket.value && socket.value.readyState === WebSocket.OPEN) {
        socket.value.close(); // 确保组件卸载时关闭WebSocket连接
    }
});


const handleSendMsg = (params: any) => {
    sendToServer(socket.value, { type: params.type, data: params.data })
}
</script>
<style lang="scss" scoped>
.main {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    border: 1px solid blue;
    box-sizing: border-box;
    display: flex;
    position: relative;

    .left {
        width: 34%;
        height: 100vh;
        border: 1px solid black;
        display: flex;
        justify-content: space-between;

        .userinfo {
            flex-shrink: 0;
            width: 80px;
            height: 100%;
            border: 1px solid red;
        }

        .friendlist {
            flex: 1;
            background-color: red;
            // width: calc(100% - 80px);
            height: 100vh;
            border: 1px solid orange;

            // .top {
            //     width: 100%;
            //     height: 100%;
            //     border: 1px solid green;
            // }
        }
    }

    .right {
        width: 60%;
        height: 100vh;
        border: 1px solid blue;
    }
}
</style>